package com.hmjk.health.background.data;

import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.text.format.Time;
import android.util.Log;

import com.hmjk.health.HealthApp;
import com.hmjk.health.background.DataManager;
import com.hmjk.health.background.DatabaseHelper;
import com.hmjk.health.background.NetService;
import com.hmjk.health.util.LOCATION_INFO;

public class DeviceLocationQuery extends DataUpdated{
	private static String TAG = DeviceLocationQuery.class.getSimpleName();
	//private static HashMap<String,LOCATION_INFO> mMap = new HashMap<String,LOCATION_INFO>();
	private static HashMap<String,LOC_TIME> mNewestTimeMap = new HashMap<String,LOC_TIME>();
	
	class LOC_TIME{
		long newest = 0;
		long update = 0;
	}
	
	private void logd(String info){
		Log.d(TAG, info);
	}
	
	public DeviceLocationQuery(HealthApp app, DataManager dm) {
		super(app, dm);
		//UPDATE_TIME = 10 * 60 * 1000;
	}

	@Override
	public void setUserData(Object data) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public long delay() {
		// TODO Auto-generated method stub
		return -1;
	}

	@Override
	public boolean grab() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean grabByUser() {
		// TODO Auto-generated method stub
		return false;
	}
	
	private void doRequest(String uid, String tid, long time){		
		int count = mApp.getLocationQueryLatestMaxCount();
		
		Intent si = new Intent(NetService.GET_DATA_ACTION);
		//si.putExtra("sub_act", NetService.GET_DEVICE_LOCATION_COUNT);
		//si.putExtra("uid", uid);
		//si.putExtra("tid", tid);
		//si.putExtra("count", String.valueOf(count));
		
		si.putExtra("sub_act", NetService.GET_DEVICE_LOCATION_NEWEST);
		si.putExtra("uid", uid);
		si.putExtra("tid", tid);
		si.putExtra("fromtimetonow", time);
		si.putExtra("maxrecord", String.valueOf(count));
		
		Time t = new Time();
		t.setToNow();
		String stamp = "GET_DEVICE_LOCATION_NEWEST" + t.toString(); 
		si.putExtra("stamp",stamp);
		mApp.addNetHandler(stamp,mDm.getBackGroundHandler());
		mApp.startService(si);
	}
	
	@Override
	public boolean grabByUserWithSingleArgs(Object args){
		DatabaseHelper dh = mDm.getDatabaseHelper();
		if(dh == null)
			return false;
		
		String tid = (String)args;
		if(tid == null)
			return false;
		
		if(tid.trim().isEmpty())
			return false;
		
		String uid = mApp.getUID();
		logd("grabByUserWithSingleArgs uid="+uid);
		if(uid == null)
			return false;
		
		LOC_TIME tinfo = mNewestTimeMap.get(tid);
		long curMs = System.currentTimeMillis();
		if(tinfo != null){
			if((curMs - tinfo.update) < MIN_QUERY_DUR * 1000){
				logd("grabByUserWithSingleArgs wait for " + MIN_QUERY_DUR + "s");
				return false;
			}
		}else{
			tinfo = new LOC_TIME();
			String table = dh.checkLocationTable(tid);
			if(table != null){
				Cursor c = dh.getNewestOneInLocationTable(table);
				if(c.getCount() > 0){
					c.moveToNext();
					tinfo.newest = c.getLong(c.getColumnIndex(DatabaseHelper.LOC_TIME));
				}
				c.close();
			}
			dh.closeDB();
			mNewestTimeMap.put(tid, tinfo);
		}
		
		doRequest(uid, tid, tinfo.newest);
		tinfo.update = curMs;
		logd("grabByUserWithSingleArgs req sent!");
		return true;
	}

	@Override
	public void receive(String stamp, String sjson) {
		DatabaseHelper dh = mDm.getDatabaseHelper();
		if(dh == null)
			return;
		
		if(stamp.startsWith("GET_DEVICE_LOCATION_NEWEST") == false)
			return;
		
		if(sjson != null){
			boolean update = false;
			String tid = "";
			try {
				JSONObject json = new JSONObject(sjson);
				int code = json.getInt("code");
				JSONObject sd = json.getJSONObject("senddata");
				if(sd != null)
					tid = sd.getString("tid");
				if(code == 200){
					String state = json.getString("state");
					if(state.equalsIgnoreCase("00")){
						JSONObject recdata = json.getJSONObject("recdata");
						LOC_TIME tinfo = mNewestTimeMap.get(tid);
						tinfo.update = System.currentTimeMillis();
						if(recdata != null){
							String table = dh.checkLocationTable(tid);
							if(table == null){
								table = dh.createLocationTable(tid);
							}
							
							if(table == null){
								Log.e("DeviceLocationQuery","no table for " + tid);
								return;
							}
							
							if(recdata.has("position")){
								JSONArray array = recdata.getJSONArray("position");
								int len = array.length();
								if(len > 0)
									update = true;
								long newest = 0;
								
								long count = dh.checkCountInTable(table);
								int max = mApp.getLocationQueryLatestMaxCount();
								if((len + count) > max){
									long delta = Math.min(len + count - max, count);
									dh.removeOldFromLocationTable(table, (len + count - max));
								}
								
								for(int i = len -1; i >=0; i--){
									JSONObject o = array.getJSONObject(i);
									ContentValues cv = new ContentValues();
									
									String slat = o.getString("lat");
									double lat = Double.parseDouble(slat);
									cv.put(DatabaseHelper.LOC_LAT, lat);
									
									String slng = o.getString("lng");
									double lng = Double.parseDouble(slng);
									cv.put(DatabaseHelper.LOC_LNG, lng);
									
									String addr = o.getString("addr");
									cv.put(DatabaseHelper.LOC_ADDR, addr);
									
									long time = o.getLong("time");
									cv.put(DatabaseHelper.LOC_TIME, time);
									
									String flag = o.getString("appendtype");
									if((flag == null) || flag.trim().isEmpty()){
										flag = "00";
									}
									int iflag = Integer.parseInt(flag);
									cv.put(DatabaseHelper.LOC_FLAG, iflag);
									
									dh.addOne2Table(table, cv);
									if(time > newest){
										newest = time;
									}
								}
								if(newest > 0){
									tinfo.newest = newest;
								}
							}
							
							dh.closeDB();
						}
					}
				}
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			Intent i = new Intent(DataManager.DATA_UPDATE_ACTION);
			i.putExtra("type",DataManager.F_DEVICE_LOCATION);
			i.putExtra("state", update);
			i.putExtra("tid", tid);
			mApp.sendBroadcast(i);
		}
		
	}

	@Override
	public Object check(String[] arg) {
		if((arg != null) && (arg.length > 0)){
			DatabaseHelper dh = mDm.getDatabaseHelper();
			if(dh == null)
				return null;
			
			int size = arg.length;
			LOCATION_INFO[] list = new LOCATION_INFO[size];
			for(int i=0; i< size;i++){
				String tid = arg[i];
				LOC_TIME tinfo = mNewestTimeMap.get(tid);
				
				String table = null;
				if(tinfo == null){
					tinfo = new LOC_TIME();
					table = dh.checkLocationTable(tid);
					if(table != null){
						Cursor c = dh.getNewestOneInLocationTable(table);
						if(c.getCount() > 0){
							c.moveToNext();
							tinfo.newest = c.getLong(c.getColumnIndex(DatabaseHelper.LOC_TIME));
						}
						c.close();
					}
					mNewestTimeMap.put(tid, tinfo);
				}else{
					table = dh.checkLocationTable(tid);
				}
				
				list[i] = new LOCATION_INFO(tid);
				list[i].upTime = tinfo.update;
				
				if(table == null){
					continue;
				}
				
				Cursor c = dh.getItemsInTable(table);
				if(c.getCount() > 0){
					while(c.moveToNext()){
						double lat = c.getDouble(c.getColumnIndex(DatabaseHelper.LOC_LAT));
						double lng = c.getDouble(c.getColumnIndex(DatabaseHelper.LOC_LNG));
						String addr = c.getString(c.getColumnIndex(DatabaseHelper.LOC_ADDR));
						long time = c.getLong(c.getColumnIndex(DatabaseHelper.LOC_TIME));
						int flag = c.getInt(c.getColumnIndex(DatabaseHelper.LOC_FLAG));
						list[i].insertItem(new LOCATION_INFO.LOC_DETAIL(lat,lng,addr,time,flag));
					}
				}
				c.close();
			}
			dh.closeDB();
			return list;
		}
		return null;
	}

	@Override
	public boolean commit(Object data) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void release() {
		// TODO Auto-generated method stub
		
	}
}
